package com.magiccompass.alipay.barcode.signature;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Map;
import java.util.Base64;

import com.magiccompass.alipay.barcode.constants.AlipayPartnerConstants;
import com.magiccompass.alipay.barcode.exception.StandardException;
import com.magiccompass.alipay.barcode.util.StringUtil;
import com.magiccompass.alipay.barcode.util.CollectionUtil;
import com.magiccompass.alipay.barcode.util.StreamUtil;

public class RSASignature {
    public static String rsaSign(Map<String, String> params, String privateKey, String charset) throws Exception {    	
    	String signContent = CollectionUtil.parameterMap2SignString(params);
		return rsaSign(signContent, privateKey, charset);	
	}
    
    private static String rsaSign(String content, String privateKey, String charset) throws StandardException {
		try {
			PrivateKey priKey = getPrivateKeyFromPKCS8(AlipayPartnerConstants.SIGN_TYPE,new ByteArrayInputStream(privateKey.getBytes()));			
			java.security.Signature signature = java.security.Signature.getInstance(AlipayPartnerConstants.SIGN_ALGORITHMS);
			
			signature.initSign(priKey);
			
			if (StringUtil.isEmpty(charset)) {
				signature.update(content.getBytes());
			} else {
				signature.update(content.getBytes(charset));
			}
			
			byte[] signed = signature.sign();
			
			String returnSign = new String(Base64.getEncoder().encode(signed));
			//System.out.println("sign:"+returnSign);
			return returnSign;
		} catch (Exception e) {
			throw new StandardException("RSAcontent:" + content + "; charset:" + charset, e);
		}
	}
    
    private static PrivateKey getPrivateKeyFromPKCS8(String algorithm, InputStream ins) throws Exception {
		if (ins == null || StringUtil.isEmpty(algorithm)) {
			return null;
		}		
		KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
		byte[] encodedKey = StreamUtil.readText(ins).getBytes();
		
		byte[] decodedKey = Base64.getDecoder().decode(encodedKey);		
		return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(decodedKey));
	}
    
    public static void main(String[] args){
    	String content = "_input_charset=UTF-8&alipay_seller_id=2088021966645500&biz_product=OVERSEAS_MBARCODE_PAY&buyer_identity_code=1234567890&currency=AUD&identity_code_type=barcode&partner=2088021966645500&partner_trans_id=86&service=alipay.acquire.overseas.spot.pay&trans_amount=6.35&trans_create_time=20160321142054&trans_name=PAYMENT_TO_MAGIC_COMPASS";
		try {
			String sign = RSASignature.rsaSign(content, AlipayPartnerConstants.SELF_PRIVATE_KEY, AlipayPartnerConstants._INPUT_CHAR_SET);
			System.out.println("sign:"+sign);
		} catch (StandardException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
